package fr.gaulupeau.apps.Poche.tts.source.webveiw;

import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebView;

import androidx.annotation.RequiresApi;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

import fr.gaulupeau.apps.Poche.tts.TtsConverter;
import fr.gaulupeau.apps.Poche.tts.bean.Article;
import fr.gaulupeau.apps.Poche.tts.source.AbstractTextInterface;
import fr.gaulupeau.apps.Poche.tts.item.ImageItem;
import fr.gaulupeau.apps.Poche.tts.item.TextItem;
import fr.gaulupeau.apps.Poche.tts.utils.TextTools;
import fr.gaulupeau.poche.tts.BuildConfig;
import fr.gaulupeau.poche.tts.R;

/**
 * TextInterface to navigate in a WebView.
 */
public class WebViewText extends AbstractTextInterface<WebViewTtsHost> {

    private static final String TAG = WebViewText.class.getSimpleName();

    private static  String JS_PARSE_DOCUMENT_SCRIPT= null;

    public WebViewText(TtsConverter ttsConverter, WebViewTtsHost ttsHost) {
        super(ttsConverter, ttsHost);
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public void parseWebViewDocument(Runnable callback) {
        Log.d(TAG, "parseWebViewDocument()");

        parsingFinishedCallback = callback;

        ttsHost.getJsTtsController().setWebViewText(this);
        ttsHost.getWebView().evaluateJavascript("javascript:" + ttsParserScriptString()
                + ";parseDocumentText();", null);
    }

    void onDocumentParseStart() {
        Log.d(TAG, "onDocumentParseStart()");
    }

    void onDocumentParseEnd() {
        Log.d(TAG, "onDocumentParseEnd()");

        if (parsingFinishedCallback != null) {
            parsingFinishedCallback.run();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    void onDocumentParseText(String text, float top, float bottom, String extras) {
        top = convertWebViewToScreenY(top);
        bottom = convertWebViewToScreenY(bottom);

        if (BuildConfig.DEBUG) {
            Log.v(TAG, String.format("onDocumentParseText(%s, %f, %f)", text, top, bottom));
        }

        addItem(new TextItem(text, top, bottom, parseTextItemExtras(extras)));
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private List<TextItem.Extra> parseTextItemExtras(String extrasString) {
        if (TextUtils.isEmpty(extrasString)) return null;

        List<TextItem.Extra> result = new ArrayList<>();

        try {
            JSONArray jsonArray = new JSONArray(extrasString);

            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);

                TextItem.Extra.Type type = TextItem.Extra.Type.getType(
                        jsonObject.getString("type"));

                TextItem.Extra extra = new TextItem.Extra(type,
                        jsonObject.getInt("start"), jsonObject.getInt("end"));

                result.add(extra);
            }
        } catch (Exception e) {
            Log.w(TAG, "parseExtras()", e);
        }

        return result;
    }

    void onDocumentParseImage(String altText, String title, String src, float top, float bottom) {
        top = convertWebViewToScreenY(top);
        bottom = convertWebViewToScreenY(bottom);

        if (BuildConfig.DEBUG) {
            Log.v(TAG, String.format("onDocumentParseImage(%s, %s, %s, %f, %f)",
                    altText, title, src, top, bottom));
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            addItem(new ImageItem(altText, title, src, top, bottom));
        }
    }


    private float convertWebViewToScreenY(float y) {
        if (ttsHost == null) {
            Log.w(TAG, "convertWebViewToScreenY() ttsHost is null");
            return 0;
        }

        WebView webView = ttsHost.getWebView();
        return y * webView.getHeight() / webView.getContentHeight();
    }

     private String ttsParserScriptString() {
        if(JS_PARSE_DOCUMENT_SCRIPT==null)
            JS_PARSE_DOCUMENT_SCRIPT=TextTools.readRawString(ttsHost.getWebView().getContext(), R.raw.tts_parser);
         return JS_PARSE_DOCUMENT_SCRIPT;
     }

    @Override
    public Article getAlbum() {
        return new Article(9999,null,ttsHost.getWebView().getTitle(),null,null);
    }
}
